In [1]:
graph = {'A': set(['B', 'C']),
'B': set(['A', 'D', 'E']),
'C': set(['A', 'F']),
'D': set(['B']),
'E': set(['B', 'F']),
'F': set(['C', 'E'])}
In [2]:
def dfs(graph, start):
visited, stack = (set(), [start])
while stack:
curr = stack.pop()
print "Outside: ", curr, "->", visited, stack
if curr not in visited:
visited.add(curr)
stack.extend(graph[curr] - visited)
return visited
dfs(graph, "A")
Out[2]:
In [3]:
def dfs_paths(graph, start, goal):
stack = [(start, [start])]
while stack:
curr, path = stack.pop()
for next in graph[curr] - set(path):
if next == goal:
print path + [next]
else:
stack.append((next, path + [next]))
dfs_paths(graph, "A", "F")
In [4]:
def bfs(graph, start):
visited, queue = (set(), [start])
while queue:
print "Visited: %s, Queue: %s" % (visited, queue)
curr = queue.pop(0)
print "Outside: ", curr
if curr not in visited:
visited.add(curr)
for k in graph[curr] - visited:
queue.extend(graph[k] - visited)
visited = visited.union(graph[curr])
#print "Curr: %s, Edges: %s" % (curr, graph[curr])
return visited
bfs(graph, "A")
Out[4]:
In [5]:
def bfs(graph, start):
visited, queue = (set(), [start])
while queue:
print "Visited: %s, Queue: %s" % (visited, queue)
curr = queue.pop(0)
print "Outside: ", curr
if curr not in visited:
visited.add(curr)
queue.extend(graph[curr] - visited)
return visited
bfs(graph, "A")
Out[5]:
In [6]:
def bfs_paths(graph, start, goal):
queue = [(start, [start])]
while queue:
curr, path = queue.pop(0)
for next in graph[curr] - set(path):
if next == goal:
print path + [next]
else:
queue.append((next, path + [next]))
bfs_paths(graph, "A", "F")
In [7]:
def shortest_path(graph, start, goal):
queue = [(start, [start])]
while queue:
curr, path = queue.pop(0)
for next in graph[curr] - set(path):
if next == goal:
return path + [next]
else:
queue.append((next, path + [next]))
return None
for k in graph.keys():
print "A", k, shortest_path(graph, "A", k)
In [8]:
def append_bst(graph, root, item):
if root is None:
graph[item] = [None, None]
return graph
curr = root
while (item < curr) or (item > curr):
if item < curr:
if graph[curr][0] is not None:
curr = graph[curr][0]
else:
graph[curr][0] = item
graph[item] = [None, None]
elif item > curr:
if graph[curr][1] is not None:
curr = graph[curr][1]
else:
graph[curr][1] = item
graph[item] = [None, None]
return graph
def gen_bst(arr):
graph = append_bst({}, None, arr[0])
root = arr[0]
for item in arr[1:]:
graph = append_bst(graph, root, item)
#print item, graph
return graph, root
In [9]:
print "Final graph:\n", gen_bst(range(10))
In [10]:
print "Final graph:\n", gen_bst([4,5,3,2,10,1,7])
In [11]:
def print_graph(graph, root):
visited, queue = (set([None]), [root])
level = 0
while queue:
curr = queue.pop(0)
print curr
if curr not in visited:
visited.add(curr)
queue.extend(set(graph[curr]) - visited)
In [12]:
print_graph(*gen_bst([4,5,3,2,10,1,7]))
In [13]:
min([1, 2, 3])
Out[13]:
In [14]:
def is_bst(graph, root):
if root is None:
return True
visited, stack = (set([None]), [root])
while stack:
curr = stack.pop()
left, right = graph[curr]
if left is not None and left > curr:
# Left is always smaller than parent
return False
if right is not None and right < curr:
# Right is always greater than parent
return False
if curr not in visited:
visited.add(curr)
print curr
stack.extend(set(graph[curr]) - visited)
return True
In [15]:
graph, root = gen_bst([4,5,3,2,10,1,7])
is_bst(graph, root)
Out[15]:
In [16]:
graph = {0: [1,2],
1: [None, None],
2: [None, None]}
root = 0
is_bst(graph, root)
Out[16]:
In [17]:
def npaths(N=10):
mat = [[0]*N for k in range(N)]
mat[0][0] = 1
for i in range(N):
for j in range(N):
if mat[i][j] == 0:
if i == 0:
mat[i][j] = mat[i][j-1] # Only one movement from left cell
#print "mat[%s][%s] = mat[%s][%s]" % (i,j,i,j-1)
#print_mat(mat)
elif j == 0:
mat[i][j] = mat[i-1][j] # Only one movement from top cell
#print "mat[%s][%s] = mat[%s][%s]" % (i,j,i-1,j)
else:
mat[i][j] = mat[i-1][j] + mat[i][j-1]
#print "mat[%s][%s] = mat[%s][%s]+1" % (i,j,i-1,j-1)
return mat
def print_mat(mat):
for row in mat:
print row
In [18]:
print_mat(npaths(N=2))
In [19]:
print_mat(npaths(N=3))
In [20]:
print_mat(npaths(N=10))
Get middle element:
Stop when middle number such that left is higher and right is higher
In [21]:
def find_smallest(arr):
left, right = 0, len(arr)
mid = (left + right) /2
i = 1
while mid > 0 and mid < len(arr)-1 and i < len(arr):
if arr[mid-1] <= arr[mid] and arr[mid+1] >= arr[mid]:
right = mid
elif arr[mid-1] >= arr[mid] and arr[mid+1] <= arr[mid]:
left = mid
else:
break
mid = (left + right) /2
i += 1
print "Iterations required: ", i
return arr[mid]
In [22]:
find_smallest([1])
Out[22]:
In [23]:
find_smallest([1,2,3])
Out[23]:
In [24]:
find_smallest([10,9,8,7,11,12,13,14])
Out[24]:
In [25]:
find_smallest([3,2,1])
Out[25]:
Characters of each string s1 and s2 will appear in the same order they appear in the original string. All characters of s1 and s2 must be exhausted.
E.g.
s1 = "aaab"
s2 = "aaac"
s3 = "aaaacaab" # is_interleaved = True
s3 = "aaaacaa" # is_interleaved = False, as b is not present in s3
s3 = "aaaacaad" # is_interleaved = False, as d is not present in s1 or s2
Approach: If s[i+j] can be formed by inteleaving s1[i-1] and s2[j] or s1[i] and s2[j-1] then s3[i+j+1] can just be formed by just matching the next character.
In [34]:
from pprint import pprint
In [141]:
mat = []
def f(s1,s2,s3,i,j):
if i < 0 and j < 0:
return True
if i < 0:
return (s3[:j+1] == s2[:j+1])
if j < 0:
return (s3[:i+1] == s1[:i+1])
if mat[i][j] == -1:
mat[i][j] = (
(f(s1,s2,s3,i-1,j) and (s3[i+j+1] == s1[i]))
or (f(s1,s2,s3,i,j-1) and (s3[i+j+1] == s2[j]))
)
return mat[i][j]
def is_interleaved(s1,s2,s3):
global mat
if len(s1) == 0 and len(s2) == 0 and len(s3) == 0:
return True
if len(s3) != (len(s1) + len(s2)):
return False
l_s1, l_s2 = len(s1), len(s2)
mat = [[-1]*(l_s2) for i in xrange(l_s1)]
for i in xrange(l_s1):
for j in xrange(l_s2):
check = f(s1,s2,s3,i,j)
#print i,j, i+j+1, s1[:i+1], s2[:j+1], s3[:i+j+2], check
#pprint(mat)
return mat[-1][-1]
In [142]:
s1 = "aaab"
s2 = "aaac"
for s3 in ["aaaacaab", "aaaacaa", "aaaacaad", "aaaadaad", ""]:
print "'%s'\t%s" % (s3, is_interleaved(s1, s2, s3))
In [143]:
s1 = "hello"
s2 = "world"
for s3 in ["worldhello", "heworlllod", "helloworld", ""]:
print "'%s'\t%s" % (s3, is_interleaved(s1, s2, s3))
In [144]:
s1 = ""
s2 = ""
for s3 in ["worldhello", "heworlllod", "helloworld", ""]:
print "'%s'\t%s" % (s3, is_interleaved(s1, s2, s3))
In [124]:
pprint(mat)
In [ ]: